package com.module.app.utils;

import android.content.res.Configuration;

import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;

import com.module.app.base.BaseApplication;
import com.module.app.bean.SkinBean;
import com.module.app.pop.CommonPop;
import com.module.app.bean.IType;
import com.module.app.bean.IType;
import com.module.app.bean.SkinBean;
import com.module.base.cache.CacheSDK;
import com.module.base.utils.ForegroundCallbacks;
import com.module.base.utils.LogUtils;
import com.module.base.utils.TimeUtils;
import com.module.base.utils.ToastUtils;
import com.module.frame.app.AppManager;
import com.module.skin.SkinUtils;

import java.util.Calendar;
import java.util.concurrent.TimeUnit;

import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

/**
 * 自动夜间模式
 */
public class AutoSkinNightUtils {
    static Disposable disposable;

    public static final String skin_night = "skin_night";
    private static boolean isNight;//是否是自动设置夜间了，，当自动设置夜间了，则主题选择失效不能选择

    public static void setType(@IType.IAutoNight int type) {
        CacheSDK.put(IType.ICache.AUTO_SKIN_NIGHT, type);
        dispose();
        switch (type) {
            case IType.IAutoNight.TYPE_NO:
                setSkin(false);
                break;
            case IType.IAutoNight.TYPE_SYSTEM:
                followSystem();
                break;
            case IType.IAutoNight.TYPE_TIME:
                countdown();
                break;

        }
        if (type == IType.IAutoNight.TYPE_TIME) {
            countdown();
        } else {
            dispose();
        }
    }

    public static void setType(@IType.IAutoNight int type, long start, long end) {
        CacheSDK.put(IType.ICache.AUTO_SKIN_NIGHT_START, start);
        CacheSDK.put(IType.ICache.AUTO_SKIN_NIGHT_END, end);
        setType(type);
    }

    public static int getType() {
        int type = CacheSDK.get(IType.ICache.AUTO_SKIN_NIGHT, Integer.class);
        return type;
    }

    public static boolean setStartTime(long hours, long minutes) {
        long time = (minutes * 1000 * 60);
        time += (hours * 1000 * 60 * 60);
        if (time == getEndTime()) {
            ToastUtils.showShort("开始时间跟结束时间不能一样");
            return false;
        }
        CacheSDK.put(IType.ICache.AUTO_SKIN_NIGHT_START, time);
        countdown();
        return true;
    }

    public static long getStartTime() {
        long time = CacheSDK.get(IType.ICache.AUTO_SKIN_NIGHT_START, Long.class);
        return time;
    }

    public static boolean setEndTime(long hours, long minutes) {
        long time = (minutes * 1000 * 60);
        time += (hours * 1000 * 60 * 60);
        if (time == getStartTime()) {
            ToastUtils.showShort("开始时间跟结束时间不能一样");
            return false;
        }
        CacheSDK.put(IType.ICache.AUTO_SKIN_NIGHT_END, time);
        countdown();
        return true;
    }

    public static long getEndTime() {
        long time = CacheSDK.get(IType.ICache.AUTO_SKIN_NIGHT_END, Long.class);
        return time;
    }


    /**
     * 绑定Activity,
     * 正常使用MainActivity
     */
    public static void bindActivity(FragmentActivity activity) {
        countdown();
        ForegroundCallbacks.Listener listener = new ForegroundCallbacks.Listener() {
            @Override
            public void onBecameForeground() {
                countdown();
            }

            @Override
            public void onBecameBackground() {
                dispose();
            }
        };
        activity.getLifecycle().addObserver(new LifecycleObserver() {

            @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
            public void onCreate() {
                ForegroundCallbacks.get(activity).addListener(listener);
            }

            @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
            public void onDestroy() {
                dispose();
                ForegroundCallbacks.get(activity).removeListener(listener);
            }
        });
    }

    /**
     * 由于我们已经禁止app根据系统夜间 自动调整app夜间（巨丑，不使用）
     * 而是用下面此方法
     * 监听系统夜间，来调整我们的夜间主题
     */
    public static void followSystem() {
        if (AutoSkinNightUtils.getType() != IType.IAutoNight.TYPE_SYSTEM) {
            return;
        }
        int currentNightMode = BaseApplication.getContext().getResources().getConfiguration().uiMode &
            Configuration.UI_MODE_NIGHT_MASK;

        boolean isOpenNight = false;
        switch (currentNightMode) {
            case Configuration.UI_MODE_NIGHT_NO://系统夜间是否关闭
                //恢复之前的主题
                isOpenNight = false;
                break;
            case Configuration.UI_MODE_NIGHT_YES://系统夜间是否开启
                //开启夜间主题
                isOpenNight = true;
                break;
            default:
                break;
        }

        setSkin(isOpenNight);
    }

    /**
     * 自定义时间，根据时间进行调整夜间模式
     */
    public static void countdown() {
        if (AutoSkinNightUtils.getType() != IType.IAutoNight.TYPE_TIME) {
            return;
        }
        if (disposable != null) {
            disposable.dispose();
        }
        disposable = Flowable
            .interval(0, 10, TimeUnit.SECONDS)//延时0s，间隔10s，体验最好是1s,但是没必要那么频繁。
            .map(new Function<Long, Boolean>() {
                @Override
                public Boolean apply(Long aLong) throws Exception {
                    long startTime = getStartTime();
                    long endTime = getEndTime();
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTimeInMillis(System.currentTimeMillis());
                    long hours = calendar.get(Calendar.HOUR_OF_DAY);
                    long minutes = calendar.get(Calendar.MINUTE);
                    long time = (minutes * 1000 * 60);
                    time += (hours * 1000 * 60 * 60);
                    boolean isOpenNight = false;
                    if (endTime > startTime) {
                        //当结束时间大于开始时间，则区间为  startTime ~ endTime

                        if (time >= startTime && time <= endTime) {
                            isOpenNight = true;
                        } else {
                            isOpenNight = false;
                        }
                    } else {
                        //当结束时间小于开始时间，则区间为  startTime ~ 0点 ~ endTime

                        //跟上面的相反过来
                        if (time >= endTime && time <= startTime) {
                            isOpenNight = false;
                        } else {
                            isOpenNight = true;
                        }
                    }
                    isNight = isOpenNight;
                    //true，为夜间模式，false为之前模式
                    return isOpenNight;
                }
            })
            .map(new Function<Boolean, String>() {
                @Override
                public String apply(@NonNull Boolean isOpenNight) throws Exception {
                    return getSkinName(isOpenNight);
                }
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .doOnNext(new Consumer<String>() {
                @Override
                public void accept(String skinName) throws Exception {
                    LogUtils.e("设置皮肤：" + skinName);
                    if (skinName != null && skinName.equals("no")) {
                        //如果等于no，则不设置，避免频繁设置
                    } else {
                        SkinUtils.INSTANCE.setSDSkin(skinName);
                        if (skinName != null && skinName.equals(skin_night)) {
                            new CommonPop.Builder(AppManager.getInstance().currentActivity())
                                .setContent(String.format("您设置的 %s~%s 自动开启夜间模式，现在时间在区域中，自动为您打开夜间模式",
                                    TimeUtils.getDate(TimeUtils.getToday() + getStartTime(), "HH:mm"), TimeUtils.getDate(TimeUtils.getToday() + getEndTime(), "HH:mm")))
                                .show();
                        } else {
                            new CommonPop.Builder(AppManager.getInstance().currentActivity())
                                .setContent(String.format("您设置的 %s~%s 自动开启夜间模式，现在时间不在区域中，自动为您关闭夜间模式",
                                    TimeUtils.getDate(TimeUtils.getToday() + getStartTime(), "HH:mm"), TimeUtils.getDate(TimeUtils.getToday() + getEndTime(), "HH:mm")))
                                .show();
                        }
                    }
                }
            })
            .subscribe();
    }

    /**
     * 设置皮肤
     */
    public static void setSkin(boolean isOpenNight) {
        String skinName = getSkinName(isOpenNight);
        if (skinName != null && skinName.equals("no")) {
            //如果等于no，则不设置，避免频繁设置
        } else {
            SkinUtils.INSTANCE.setSDSkin(skinName);
        }
        isNight = isOpenNight;
    }

    /**
     * 根据是否开启夜间模式，
     * 来返回主题名称
     *
     * @return no代表不需要设置
     */
    private static String getSkinName(boolean isOpenNight) {
        String name = "no";//no 代表不设置，
        if (isOpenNight) {
            //需要设置夜间模式

            if (SkinUtils.INSTANCE.isUse(skin_night)) {
                //如果已经设置了，则不需要重设置
                name = "no";
            } else {
                //设置夜间模式
                name = "skin_night";
            }
        } else {
            //恢复原先模式
            SkinBean cur = MySkinUtils.getCurSkinBean();
            if (cur == null) {
                if (SkinUtils.INSTANCE.isUse("")) {
                    name = "no";
                } else {
                    name = "";
                }
            } else if (SkinUtils.INSTANCE.isUse(cur.getSkinName())) {
                //如果已经设置了，则不需要重设置
                name = "no";
            } else {
                //设置夜间模式
                name = cur.getSkinName();
            }
        }
        //如果是默认的皮肤，可能为空
        if (name == null) {
            name = "";
        }
        return name;
    }

    public static void dispose() {
        if (disposable != null) {
            disposable.dispose();
        }
    }

    public static void destroy() {
        dispose();
    }

    /**
     * 是否开启自动夜间，且当前时间为夜间模式
     */
    public static boolean isNight() {
        return isNight;
    }
}
